use alloc::string::String;
use core::fmt::{Display, Formatter};

#[derive(Debug)]
pub enum Error {
    Inited,
    UnInit,
    NotFound,
    Empty,
    Full,
    InvalidParam,
    InvalidJson,
    InvalidJsonString(String),
    NoJsonField(String),
    InvalidJsonField(String),
    Timeout,
    Io(i32, String),
    Api(i32, String),
    ApiRef(i32, &'static str),
    Other(String),
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        match self {
            Error::Io(err, s) => f.write_fmt(format_args!("io error: {} {}", err, s)),
            Error::Api(err, s) => f.write_fmt(format_args!("io error: {} {}", err, s)),
            Error::ApiRef(err, s) => f.write_fmt(format_args!("io error: {} {}", err, s)),
            Error::InvalidParam => f.write_fmt(format_args!("invalid param error")),
            Error::InvalidJson => f.write_fmt(format_args!("invalid json")),
            Error::InvalidJsonString(s) => f.write_fmt(format_args!("invalid json: {}", s)),
            Error::InvalidJsonField(err) => f.write_fmt(format_args!("invalid json: {}", err)),
            Error::NoJsonField(err) => f.write_fmt(format_args!("no json field: {}", err)),
            Error::Timeout => f.write_fmt(format_args!("timeout error")),
            Error::Full => f.write_fmt(format_args!("full error")),
            Error::NotFound => f.write_fmt(format_args!("not found error")),
            Error::Other(s) => f.write_fmt(format_args!("other error: {}", s)),
            Error::Inited => f.write_fmt(format_args!("inited error")),
            Error::UnInit => f.write_fmt(format_args!("uninit error")),
            Error::Empty => f.write_fmt(format_args!("empty error")),
        }
    }
}

pub type Result<T> = core::result::Result<T, Error>;

pub fn map_other_err(e: String) -> Error {
    Error::Other(e)
}

pub fn map_to_int(_e: Error) -> i32 {
    -1
}

#[cfg(not(feature = "no_std"))]
impl From<std::io::Error> for Error {
    fn from(value: std::io::Error) -> Self {
        Error::Io(-1, value.to_string())
    }
}
